package com.yuanian.timingwheel.distributedlock;

import com.yuanian.timingwheel.config.JobConfig;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * DB实现的分布式锁
 */
public class DbDistributedLock<T> implements DistributedLock<T>  {

    @Override
    public T lock(String resourceName, BusinessAction<T> action) {
        Connection conn = null;
        Boolean connAutoCommit = null;
        PreparedStatement preparedStatement = null;
        try {
            conn = JobConfig.getInstance().getDataSource().getConnection();
            connAutoCommit = conn.getAutoCommit();
            conn.setAutoCommit(false);

            preparedStatement = conn.prepareStatement(  "select * from TP_TW_LOCK where lock_name = '" + resourceName + "' for update" );
            preparedStatement.execute();

            return action.doAction();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {

            // commit
            if (conn != null) {
                try {
                    conn.commit();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    conn.setAutoCommit(connAutoCommit);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            // close PreparedStatement
            if (null != preparedStatement) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
